package com.bestom.t9mod.base;

import android.os.Handler;
import android.util.Log;

import com.bestom.t9mod.base.service.SerialObservable;
import com.bestom.t9mod.base.service.SerialObserver;
import com.bestom.t9mod.commons.constant.Const;
import com.bestom.t9mod.commons.constant.KPACmdCode;
import com.bestom.t9mod.commons.constant.KPARECmdCode;
import com.bestom.t9mod.commons.constant.StatusCode;
import com.bestom.t9mod.commons.listener.DataReceivedListener;
import com.bestom.t9mod.commons.listener.ParseCallback;
import com.bestom.t9mod.commons.listener.RespSampleListener;
import com.bestom.t9mod.commons.utils.DataTurn;
import com.bestom.t9mod.commons.utils.MyUtil;

/**
 * 基础
 */
public class SerialApi {
    private static final String TAG = "SerialApi";
    private com.bestom.t9mod.commons.utils.DataTurn DataTurn =new DataTurn();

    private static Handler mHandler = new Handler();
    private SerialObserver InfoObserver = null,ResultObserver = null,ErrorObserver = null;

    /***********************************************************
     * 拼接命令
     * @param cmdCode 命令类型
     * @return 返回拼接完成命令
     */
    protected String jointCmd(KPACmdCode cmdCode) {
        return jointCmd(cmdCode, "");
    }

    /***********************************************************
     * 拼接命令
     * @param cmdCode 命令类型
     * @param bodyHex 传参体
     * @return 返回拼接完成命令
     */
    protected String jointCmd(KPACmdCode cmdCode, String bodyHex) {
        String cmd="";
        String magic= Const.Serial_Send_MAGIC;
        String cmdHex=cmdCode.getHexStr();
//        String IDHex = "01";
        String bodysizeHex,checkHex;

        if (bodyHex.equals("")){
            bodysizeHex = "03";
            checkHex = MyUtil.sumCheck(bodysizeHex+cmdHex) ;

            cmd=magic+bodysizeHex+checkHex+cmdHex;
        }else {
            Log.d(TAG, "jointCmd: send msg bodyHex not null !!!");
        }

        Log.i("jointCmd",cmd);
        return cmd;
    }

    /**************************************************************
     * 注册观察者（限定时间观察者）
     * @param code 应答类型
     * @param timeout 超时时间
     * @param listener 监听
     * @param callback 返回
     */
    protected void registerAndRemoveObserver(final KPARECmdCode code, long timeout, final RespSampleListener listener, final ParseCallback callback) {
        final boolean[] isHas = {false}; //是否存在结果数据

        final SerialObserver timeRespobserver = new SerialObserver();
        timeRespobserver.setOnDataReceivedListener(new DataReceivedListener() {
            @Override
            public void data(String dataHex) {
                Log.i(TAG, "nDataReceivedListener DATA HEX:" + dataHex);
                if (dataHex.substring(8, 10).equals(code.getHexStr())) {
                    isHas[0] = true; //存在结果数据
                    String sizeHex = dataHex.substring(4, 6);
                    int bodysize = DataTurn.HexToInt(sizeHex);
                    String checkHex = dataHex.substring(6,8);
//                    String IDHex = dataHex.substring(8,10);
                    String cmdHex = dataHex.substring(8, 10);
                    String msgHex = dataHex.substring(10);
                    int allsize = 4 + bodysize * 2;
                    Log.d(TAG,"allsize 长度为 ： " + allsize);
                    if (dataHex.length() == allsize) {
                        //region check byte
                        Log.d(TAG, "check data: "+sizeHex+cmdHex+msgHex);
                        String checkSum = MyUtil.sumCheck(sizeHex+cmdHex+msgHex);
                        Log.d(TAG, "checkSum : "+checkSum);
                        Log.d(TAG, "checkHex : "+checkHex);
                        if (checkSum.equalsIgnoreCase(checkHex)){
                            String responsebody = msgHex;
                            Log.i("Serial--response", "" + responsebody);
                            if (responsebody.equals("")){
                                listener.onSuccess(StatusCode.SUCCESS.getCode(),StatusCode.SUCCESS.getMsg());
                            }else {
                                callback.result(responsebody);
                            }
                        }else {
                            listener.onFailure(StatusCode.CHECK_ERR.getCode(),
                                    StatusCode.CHECK_ERR.getMsg());
                        }
                        //endregion
                    } else { //数据格式错误
                        Log.d(TAG,"nDataReceivedListener DATA HEX: 数据格式错误 ");
                        listener.onFailure(StatusCode.FORMAT_ERR.getCode(),
                                StatusCode.FORMAT_ERR.getMsg());
                    }
                }
            }
        });
        SerialObservable.getInstance().registerObserver(timeRespobserver);
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                //没得到数据结果，进行超时处理
                if (!isHas[0]) {
                    Log.d(TAG,"nDataReceivedListener DATA HEX: 没得到数据结果，进行超时处理 ");
                    listener.onFailure(StatusCode.TIMEOUT.getCode(),
                            StatusCode.TIMEOUT.getMsg());
                }
                SerialObservable.getInstance().removeObserver(timeRespobserver);
                mHandler.removeCallbacks(this);
            }
        }, timeout);
    }


    /**************************************************************
     * 注册观察者（无限定时间观察者）
     * @param code 应答类型
     * @param listener 监听
     * @param callback 返回
     */
    protected void noTimeregisterObserver(final KPARECmdCode code, final RespSampleListener listener, final ParseCallback callback) {
        final boolean[] isHas = {false}; //是否存在结果数据

        final SerialObserver Respobserver = new SerialObserver();
        if (code==KPARECmdCode.KPA_RECMD_INFO){
            if (InfoObserver!=null){
                SerialObservable.getInstance().removeObserver(InfoObserver);
                InfoObserver=null;
            }
            InfoObserver=Respobserver;
        }else if (code==KPARECmdCode.KPA_RECMD_RESULT){
            if (ResultObserver!=null){
                SerialObservable.getInstance().removeObserver(ResultObserver);
                ResultObserver=null;
            }
            ResultObserver=Respobserver;
        }else if (code==KPARECmdCode.KPA_RECMD_ERROR){
            if (ErrorObserver!=null){
                SerialObservable.getInstance().removeObserver(ErrorObserver);
                ErrorObserver=null;
            }
            ErrorObserver=Respobserver;
        }
        Respobserver.setOnDataReceivedListener(new DataReceivedListener() {
            @Override
            public void data(String dataHex) {
                Log.i(TAG, "nDataReceivedListener DATA HEX:" + dataHex);
                if (dataHex.substring(8, 10).equals(code.getHexStr())) {
                    isHas[0] = true; //存在结果数据
                    String sizeHex = dataHex.substring(4, 6);
                    int bodysize = DataTurn.HexToInt(sizeHex);
                    String checkHex = dataHex.substring(6,8);
//                    String IDHex = dataHex.substring(8,10);
                    String cmdHex = dataHex.substring(8,10);
                    String msgHex = dataHex.substring(10);
                    int allsize = 4 + bodysize * 2;
                    if (dataHex.length() == allsize) {
                        //region check byte
                        Log.d(TAG, "check data: "+sizeHex+cmdHex+msgHex);
                        String checkSum = MyUtil.sumCheck(sizeHex+cmdHex+msgHex);
                        Log.d(TAG, "checkSum : "+checkSum);
                        Log.d(TAG, "checkHex : "+checkHex);
                        if (checkSum.equalsIgnoreCase(checkHex)){
                            String responsebody = msgHex;
                            Log.i("Serial--response", "" + responsebody);
                            if (responsebody.equals("")){
                                listener.onSuccess(StatusCode.SUCCESS.getCode(),StatusCode.SUCCESS.getMsg());
                            }else {
                                callback.result(responsebody);
                            }
                        }else {
                            listener.onFailure(StatusCode.CHECK_ERR.getCode(),
                                    StatusCode.CHECK_ERR.getMsg());
                        }
                        //endregion
                    } else { //数据格式错误
                        listener.onFailure(StatusCode.FORMAT_ERR.getCode(),
                                StatusCode.FORMAT_ERR.getMsg());
                    }
                }
            }
        });
        SerialObservable.getInstance().registerObserver(Respobserver);
    }

    protected void removeObserver(KPARECmdCode kpareCmdCode){
        switch (kpareCmdCode){
            case KPA_RECMD_INFO:
                if (InfoObserver!=null){
                    SerialObservable.getInstance().removeObserver(InfoObserver);
                    InfoObserver=null;
                }
                break;
            case KPA_RECMD_RESULT:
                if (ResultObserver!=null){
                    SerialObservable.getInstance().removeObserver(ResultObserver);
                    ResultObserver=null;
                }
                break;
            case KPA_RECMD_ERROR:
                if (ErrorObserver!=null){
                    SerialObservable.getInstance().removeObserver(ErrorObserver);
                    ErrorObserver=null;
                }
                break;
            default:
                break;
        }
    }

    protected void ClearObserver(){
        SerialObservable.getInstance().clean();
    }

}
